//
//  ST_QuickMessageViewController.swift
//  btvideo
//
//  聊天快捷消息弹窗
//
//  Created by mac on 2021/9/6.
//  Copyright © 2021 JarvanZhang. All rights reserved.
//

import UIKit
import RxSwift
import RxCocoa

/// 缓存url
let quickMessageCacheURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!

class ST_QuickMessageViewController: UIViewController {

    /// 卡片背景
    let bgView: UIView = {
        let view = UIView()
        view.backgroundColor = .white
        return view
    }()
    
    /// 点击关闭弹窗手势
    lazy var dismiss_tap: UITapGestureRecognizer = {
        let tap = UITapGestureRecognizer()
        tap.delegate = self
        return tap
    }()
    
    /// 标题
    let titleLabel: UILabel = {
        let label = UILabel()
        label.text = "快捷搭讪"
        label.textColor = UIColor(hexString: "#333333")
        label.font = .systemFont(ofSize: 18, weight: .medium)
        return label
    }()
    
    /// 删除按钮
    let delete_button: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("删除", for: .normal)
        button.setTitleColor(UIColor(hexString: "#ACB4C0"), for: .normal)
        button.titleLabel?.font = .systemFont(ofSize: 14, weight: .medium)
        return button
    }()
    
    /// 添加按钮
    let add_button: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("添加", for: .normal)
        button.setTitleColor(UIColor(hexString: "#ACB4C0"), for: .normal)
        button.titleLabel?.font = .systemFont(ofSize: 14, weight: .medium)
        return button
    }()
    
    /// 顶部标题栏布局
    lazy var title_stack_view: UIStackView = {
        let stackView = UIStackView()
        stackView.axis = .horizontal
        stackView.distribution = .equalSpacing
        stackView.alignment = .center
        stackView.addArrangedSubviews([delete_button, titleLabel, add_button])
        return stackView
    }()
    
    /// 分类标签
    lazy var category_collection_view: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
        layout.minimumLineSpacing = 10
        layout.itemSize = CGSize(width: 60, height: 30)
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.backgroundColor = .clear
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.register(cellWithClass: ST_QuickMessageTagItem.self)
        collectionView.dataSource = self
        collectionView.delegate = self
        return collectionView
    }()
    
    /// 内容
    lazy var content_collection_view: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        layout.itemSize = CGSize(width: view.width - 32, height: 46)
        layout.minimumLineSpacing = 10
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.backgroundColor = .clear
        collectionView.register(cellWithClass: ST_QuickMessageContentItem.self)
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.emptyDataSetSource = self
        collectionView.emptyDataSetDelegate = self
        return collectionView
    }()
    
    /// 播放录音控制器
    let recorder_controller = ST_RecorderController()
    
    var disposeBag = DisposeBag()
    let viewModel = ST_QuickMessageViewModel()
    
    /// 发送文字消息
    var onSendTextMessage: ((String) -> Void)? = nil
    /// 发送语音消息
    var onSendVoiceMessage: ((String, Int) -> Void)? = nil
    
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        
        overCurrentContext = true
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        setup_views()
        bindRx()
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        bgView.roundCorners([.topLeft, .topRight], radius: 16)
    }
    
    @available(iOS 11.0, *)
    override func viewSafeAreaInsetsDidChange() {
        super.viewSafeAreaInsetsDidChange()
        
        bgView.snp.updateConstraints { make in
            make.height.equalTo(375 + view.safeAreaInsets.bottom)
        }
    }

    func setup_views() {
        
        view.addGestureRecognizer(dismiss_tap)
        
        view.addSubview(bgView)
        bgView.snp.makeConstraints { make in
            make.leading.bottom.trailing.equalToSuperview()
            make.height.equalTo(375)
        }
        
        bgView.addSubview(title_stack_view)
        title_stack_view.snp.makeConstraints { make in
            make.top.equalToSuperview()
            make.leading.trailing.equalToSuperview().inset(16)
            make.height.equalTo(65)
        }
        
        bgView.addSubview(category_collection_view)
        category_collection_view.snp.makeConstraints { make in
            make.top.equalTo(title_stack_view.snp.bottom).offset(8)
            make.leading.trailing.equalToSuperview()
            make.height.equalTo(30)
        }
        
        bgView.addSubview(content_collection_view)
        content_collection_view.snp.makeConstraints { make in
            make.top.equalTo(category_collection_view.snp.bottom).offset(30)
            make.leading.trailing.equalToSuperview()
            make.bottom.equalToSuperview()
        }
    }
    
    func bindRx() {
        
        viewModel.errorSubject
            .subscribe(onNext: { [weak self] error in
                self?.toast(text: error.localizedDescription)
            })
            .disposed(by: disposeBag)
        
        dismiss_tap.rx.event
            .filter { $0.state == .ended }
            .asDriver(onErrorJustReturn: dismiss_tap)
            .drive(onNext: { [weak self] _ in
                self?.dismiss(animated: true)
            })
            .disposed(by: disposeBag)
        
        viewModel.editStateText
            .bind(to: delete_button.rx.title())
            .disposed(by: disposeBag)
        
        delete_button.rx.tap
            .subscribe(onNext: { [weak self] in
                guard let self = self else { return }
                self.recorder_controller.stop_playing()
                self.viewModel.isEditing.accept(!self.viewModel.isEditing.value)
            })
            .disposed(by: disposeBag)
        
        viewModel.selectedCategory
            .subscribe(onNext: { [weak self] _ in
                self?.recorder_controller.stop_playing()
                self?.category_collection_view.reloadData()
                self?.content_collection_view.reloadData()
                self?.content_collection_view.reloadEmptyDataSet()
            })
            .disposed(by: disposeBag)
        
        Observable.combineLatest(viewModel.isEditing, viewModel.textList, viewModel.voiceList)
            .asDriver(onErrorJustReturn: (false, [], []))
            .drive(onNext: { [weak self] _ in
                self?.content_collection_view.reloadData()
            })
            .disposed(by: disposeBag)
        
        add_button.rx.tap
            .subscribe(onNext: { [weak self] in
                
                self?.recorder_controller.stop_playing()
                switch self?.viewModel.selectedCategory.value {
                case .text:
                    guard (self?.viewModel.textList.value.count ?? 0) < 5 else {
                        self?.toast(text: "最多只能添加5条文字消息喔～")
                        return
                    }
                    
                    let vc = ST_QuickMessageTextViewController()
                    vc.onAdd = {
                        if let category = self?.viewModel.selectedCategory.value {
                            self?.viewModel.fetchData(category: category)
                        }
                    }
                    GlobalPresent(toController: vc)
                case .voice:
                    
                    guard (self?.viewModel.voiceList.value.count ?? 0) < 5 else {
                        self?.toast(text: "最多只能添加5条语音消息喔～")
                        return
                    }
                    
                    let vc = ST_QuickMessageVoiceViewController(viewModel: ST_QuickMessageVoiceViewModel.defaultVMCreator())
                    vc.onAdd = {
                        if let category = self?.viewModel.selectedCategory.value {
                            self?.viewModel.fetchData(category: category)
                        }
                    }
                    GlobalPresent(toController: vc)
                default:
                    break
                }
            })
            .disposed(by: disposeBag)
    }
    
    /// 删除一条快捷搭讪信息
    /// - Parameters:
    ///   - id: 数据ID
    ///   - indexPath: collectionViewCell的indexPath
    func delete(_ id: Int?, indexPath: IndexPath) {
        guard let id = id else { return }
        show_indeterminate_h_u_d()
        viewModel.deleteItem(id)
            .subscribe(onSuccess: { [weak self] in
                var temp: [ST_QuickMessageModel]
                let br: BehaviorRelay<[ST_QuickMessageModel]>?
                switch self?.viewModel.selectedCategory.value {
                case .text:
                    temp = self?.viewModel.textList.value ?? []
                    br = self?.viewModel.textList
                case .voice:
                    temp = self?.viewModel.voiceList.value ?? []
                    br = self?.viewModel.voiceList
                default:
                    temp = []
                    br = nil
                }
                temp.remove(at: indexPath.item)
                br?.accept(temp)
                self?.hidden_indeterminate_h_u_d()
            }, onFailure: { [weak self] error in
                self?.toast(text: error.localizedDescription)
            })
            .disposed(by: disposeBag)
    }
}

extension ST_QuickMessageViewController: UIGestureRecognizerDelegate {
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        // 点击的view为self.view才响应tap手势
        touch.view == view
    }
}

extension ST_QuickMessageViewController: UICollectionViewDataSource {
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        1
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        switch collectionView {
        case category_collection_view:
            return viewModel.categories.count
        default:
            switch viewModel.selectedCategory.value {
            case .text:
                return viewModel.textList.value.count
            case .voice:
                return viewModel.voiceList.value.count
            default:
                return 0
            }
        }
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        switch collectionView {
        case category_collection_view:
            let cell = collectionView.dequeueReusableCell(withClass: ST_QuickMessageTagItem.self, for: indexPath)
            let category = viewModel.categories[indexPath.item]
            cell.configure(for: category, selectedCategory: viewModel.selectedCategory.value)
            return cell
        default:
            let cell = collectionView.dequeueReusableCell(withClass: ST_QuickMessageContentItem.self, for: indexPath)
            let model: ST_QuickMessageModel?
            switch viewModel.selectedCategory.value {
            case .text:
                model = viewModel.textList.value[indexPath.item]
            case .voice:
                model = viewModel.voiceList.value[indexPath.item]
            default:
                model = nil
            }
            cell.configure(for: model, isEditing: viewModel.isEditing.value)
            cell.delete_button.rx.tap
                .subscribe(onNext: { [weak self] in
                    self?.recorder_controller.stop_playing()
                    self?.delete(model?.id, indexPath: indexPath)
                })
                .disposed(by: cell.disposeBag)
            cell.voice_button.rx.tap
                .subscribe(onNext: { [weak self] in
                    guard let url = model?.content.url else { return }
                    self?.recorder_controller.play(url: url, cell: cell)
                })
                .disposed(by: cell.disposeBag)
            cell.send_button.rx.tap
                .subscribe(onNext: { [weak self] in
                    guard let self = self else { return }
                    guard let model = model else { return }
                    switch model.type {
                    case .text where model.status == .accept:
                        self.onSendTextMessage?(model.content)
                    case .voice where model.status == .accept:
                        let path = quickMessageCacheURL.appendingPathComponent(model.content).path
                        if FileManager.default.fileExists(atPath: path) {
                            self.onSendVoiceMessage?(path, model.duration.int)
                        } else {
                            self.downloadSendVoice(model: model)
                        }
                    default:
                        break
                    }
                })
                .disposed(by: cell.disposeBag)
            return cell
        }
    }
    
    
    /// 下载语音文件并缓存发送
    /// - Parameter model: 快捷搭讪消息
    func downloadSendVoice(model: ST_QuickMessageModel) {
        show_indeterminate_h_u_d()
        viewModel.cacheVoice(urlString: model.content)
            .subscribe(onSuccess: { [weak self] path in
                self?.hidden_indeterminate_h_u_d()
                self?.onSendVoiceMessage?(path, model.duration.int)
            }, onFailure: { error in
                self.toast(text: error.localizedDescription)
            })
            .disposed(by: disposeBag)
    }
}

extension ST_QuickMessageViewController: UICollectionViewDelegate {
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        switch collectionView {
        case category_collection_view:
            let category = viewModel.categories[indexPath.item]
            viewModel.selectedCategory.accept(category)
        default:
            
            let model: ST_QuickMessageModel?
            switch viewModel.selectedCategory.value {
            case .text:
                model = viewModel.textList.value[indexPath.item]
            case .voice:
                model = viewModel.voiceList.value[indexPath.item]
            default:
                model = nil
            }
            
            guard let model = model else { return }
            switch model.type {
            case .text where model.status == .accept:
                self.onSendTextMessage?(model.content)
            case .voice where model.status == .accept:
                let path = quickMessageCacheURL.appendingPathComponent(model.content).path
                if FileManager.default.fileExists(atPath: path) {
                    self.onSendVoiceMessage?(path, model.duration.int)
                } else {
                    self.downloadSendVoice(model: model)
                }
            default:
                break
            }
            
        }
    }
}

extension ST_QuickMessageViewController: DZNEmptyDataSetSource {
    
    func image(forEmptyDataSet scrollView: UIScrollView!) -> UIImage! {
        #imageLiteral(resourceName: "quickMessage_image_empty")
    }
    
    func title(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
        NSAttributedString(string: "还未添加常用\(viewModel.selectedCategory.value.title)", attributes: [.foregroundColor: UIColor(hexString: "#ACB4C0")!, .font: UIFont.systemFont(ofSize: 14, weight: .medium)])
    }
    
    func buttonImage(forEmptyDataSet scrollView: UIScrollView!, for state: UIControl.State) -> UIImage! {
        #imageLiteral(resourceName: "quickMessage_image_add")
    }
    
}

extension ST_QuickMessageViewController: DZNEmptyDataSetDelegate {
    
    func emptyDataSet(_ scrollView: UIScrollView!, didTap button: UIButton!) {
        add_button.sendActions(for: .touchUpInside)
    }
}
